#include "UdpSocket.h"
#include "SockData.h"

DEF_BEG_LIBTOOLS

CUdpSocket::CUdpSocket()
{
	_Init();
}

CUdpSocket::CUdpSocket(CBasicService* pServer)
{
	_Init();
	SetService(pServer);
}

CUdpSocket::~CUdpSocket()
{

}

#ifdef STD11
CUdpSocket::CUdpSocket(CUdpSocket&& sock)
{
	*this = std::move(sock);
}

CUdpSocket& CUdpSocket::operator= (CUdpSocket&& sock)
{
	if (this != &sock)
	{
		Close();
		_Init();
		Swap(sock);
	}

	return *this;
}
#endif

void CUdpSocket::_Init()
{
	_sockData = new UdpSocketData();
	_sockData->_sock = INVALID_SOCKET;
	_sockData->_sockaddr.SetDomain(SOCKFAMILY::IPV4);
	_sockData->_type = SOCKTYPE::DGRAM;
	_sockData->_protocol = SOCKPROTOCOL::UDP;
	_sockData->_pServerBuf.Reset(NULL);
	_sockData->_pServer = NullPtr;
	dynamic_cast<UdpSocketData*>(_sockData.Get())->_remoteSockaddr.SetDomain(SOCKFAMILY::IPV4);
}

std::string CUdpSocket::GetRemoteAddr() const
{
	std::string addr;
	dynamic_cast<UdpSocketData*>(_sockData.Get())->_remoteSockaddr.GetAddr(addr);

	return STD_MOVE(addr);
}

DWORD CUdpSocket::GetRemotePort() const
{
	return dynamic_cast<UdpSocketData*>(_sockData.Get())->_remoteSockaddr.GetPort();
}

const CSockAddr& CUdpSocket::GetRemoteSockaddr() const
{
	return dynamic_cast<UdpSocketData*>(_sockData.Get())->_remoteSockaddr;
}

CSockError CUdpSocket::Socket(SOCKFAMILY::SockFamily domain /* = SOCKFAMILY::IPV4 */, SOCKTYPE::SockType type /* = SOCKTYPE::DGRAM */, 
	SOCKPROTOCOL::SockProtocol protocol /* = SOCKPROTOCOL::UDP */)
{
	return CSocket::Socket(domain, type, protocol);
}

void CUdpSocket::SetRemoteAddr(const char* addr)
{
	dynamic_cast<UdpSocketData*>(_sockData.Get())->_remoteSockaddr.SetAddr(addr);
}

void CUdpSocket::SetRemotePort(DWORD port)
{
	dynamic_cast<UdpSocketData*>(_sockData.Get())->_remoteSockaddr.SetPort(port);
}

void CUdpSocket::SetDomain(SOCKFAMILY::SockFamily domain)
{
	if (GetDomain() != domain) 
	{
		dynamic_cast<UdpSocketData*>(_sockData.Get())->_remoteSockaddr.SetDomain(domain);
		CSocket::SetDomain(domain);
	}
}

DEF_END_LIBTOOLS